package com.example.onlinemonitoring.comCenter;

import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.autoRun.ComRunner;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.Txpdhistory;
import com.example.onlinemonitoring.model.Txpdsensor;
import org.springframework.context.annotation.Scope;
import com.example.onlinemonitoring.serviceImpl.TxpdsensorServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.net.SocketException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 铁芯接地（12路）
 */
@Service("txpdCom")
@Scope("prototype")
public class TxpdCom extends CommPortManager {
    @Autowired
    private TxpdsensorServiceImpl txpdserviceimpl;
    int flag=0;
    @Override
    public void receiveData(String str) {

        setText(str);
        float[] Current = new float[16];
        int ckaddr = 0;
        String addrstr = str.substring(0, 2);
        Integer addr = parseHex4(addrstr);
        if (ad.getBrand().equals("STOM-I/E")) {
            addrstr = str.substring(6, 8) + str.substring(4, 6);
            addr = parseHex4(addrstr);
        }

        reSend[addr] = 0;
        addrindex++;

        for (int j = 1; j <= 12; j++) {
            if (ad.getBrand().equals("STOM-I/E")) {
                if (j == 1 || j == 2) {
                    Txpdsensor txpd = new Txpdsensor();
                    txpd.setStationid(ad.getStationid());
                    txpd.setDevicegroup(ad.getDevicegroup());
                    txpd.setDeviceaddr(addr);
                    txpd.setPointaddr(j);
                    txpd = txpdserviceimpl.getModel(txpd);
                    if (txpd == null) {
                        setText("当前数据库无监测点：设备地址" + addr + "的监测点" + j + " ！ 请先添加该监测点！");
                        continue;
                    }
                    if (txpd.getInuse() == 0) {
                        continue;
                    }

                    ckaddr = ((j - 1) * 8);
                    String s = str.substring(20 + ckaddr, 28 + ckaddr);
                    byte[] mybyte_Current = HexUtil.hexString2Bytes(s);
                    Current[j] = HexUtil.byte2float(mybyte_Current);

                    SensorData(txpd, Current[j]);
                }
            } else {
                Txpdsensor txpd = new Txpdsensor();
                txpd.setStationid(ad.getStationid());
                txpd.setDevicegroup(ad.getDevicegroup());
                txpd.setDeviceaddr(addr);
                txpd.setPointaddr(j);
                txpd = txpdserviceimpl.getModel(txpd);
                if (txpd == null) {
                    setText("当前数据库无监测点：设备地址" + addr + "的监测点" + j + " ！ 请先添加该监测点！");
                    continue;
                }
                if (txpd.getInuse() == 0) {
                    continue;
                }

                ckaddr = ((j - 1) * 8);
                String s = str.substring(6 + ckaddr, 14 + ckaddr);
                byte[] mybyte_Current = HexUtil.hexString2Bytes(s);
                Current[j] = HexUtil.byte2float(mybyte_Current);

                /* 以下注释代码为20231023发货项目油温油位 */
                // if (j == 1 || j == 2) {
                // SensorData(txpd, (Current[j]) * 8 - 20);
                // } else if (j == 3 || j == 4) {
                // SensorData(txpd, (Current[j]) * 0.5f);
                // } else if (j == 5) {
                // SensorData(txpd, (Current[j]) * 8 - 20);
                // } else {
                // SensorData(txpd, Current[j] - 4);
                // }
                // if(flag==1)
                // {
                //      val =0;       
                // }
                // else
                // val = Current[j] / 2 * 1000;
                SensorData(txpd,  Current[j] / 2 * 1000);
            }
        }

    }
    public void read61850BSQ(String str) {
        Txpdsensor currrecord = new Txpdsensor();
        currrecord.setStationid(ad.getStationid());
        currrecord.setDevicegroup(ad.getDevicegroup());
        currrecord.setInuse(1);
        List<Txpdsensor> lastrecordlist = txpdserviceimpl.getLists(currrecord);
        if (lastrecordlist.size() != 0) {
            if (lastrecordlist.get(0).getStyle61850() != null) {
                String[] style = lastrecordlist.get(0).getStyle61850().split(",");
                for (String s : style) {
                    map61850.put(s.split("\\|")[0], s.split("\\|")[1]);
                }
            }
        }
        for (Txpdsensor lastrecord : lastrecordlist) {
            try {
                lastrecord.setLastcommunicationstatus(read61850IntValue(
                        String.format(isnull(map61850.get("MoDevConf")), lastrecord.getDeviceaddr())));
            } catch (SocketException e) {
                if (Close()) {
                    txpdserviceimpl.UpdateStatus(ad, 1);
                    ComRunner.netmap.remove(ad.getId());
                }
            } catch (Exception e) {
                setText("读取数据出错！" + e.toString());
            }
            String alm = "";
            try {
            currrecord.setLastdata(
                read61850FloatValue(
                        String.format(isnull(map61850.get("CGAmp")), lastrecord.getDeviceaddr(),
                                lastrecord.getPointaddr())));
            alm += read61850IntValue(
                String.format(isnull(map61850.get("CGAlm")), lastrecord.getDeviceaddr())) == 1 ? "铁芯全电流告警,"
                        : "";
                } catch (SocketException e) {
                    if (Close()) {
                        txpdserviceimpl.UpdateStatus(ad, 1);
                        ComRunner.netmap.remove(ad.getId());
                    }
                } catch (Exception e) {
                    setText("读取数据出错！" + e.toString());
                }
            SensorData(lastrecord, currrecord.getLastdata());
        }
    }


    public void read61850(String str) {
        Txpdsensor currrecord = new Txpdsensor();
        currrecord.setStationid(ad.getStationid());
        currrecord.setDevicegroup(ad.getDevicegroup());
        currrecord.setInuse(1);
        List<Txpdsensor> lastrecordlist = txpdserviceimpl.getLists(currrecord);
        if (lastrecordlist.size() != 0) {
            if (lastrecordlist.get(0).getStyle61850() != null) {
                String[] style = lastrecordlist.get(0).getStyle61850().split(",");
                for (String s : style) {
                    map61850.put(s.split("\\|")[0], s.split("\\|")[1]);
                }
            }
        }
        for (Txpdsensor lastrecord : lastrecordlist) {
            try {
                lastrecord.setLastcommunicationstatus(read61850IntValue(
                        String.format(isnull(map61850.get("MoDevConf")), lastrecord.getDeviceaddr())));
            } catch (SocketException e) {
                if (Close()) {
                    txpdserviceimpl.UpdateStatus(ad, 1);
                    ComRunner.netmap.remove(ad.getId());
                }
            } catch (Exception e) {
                setText("读取数据出错！" + e.toString());
            }

            if (lastrecord.getPointaddr() == 9) {
                String alm = "";
                try {
                    currrecord.setLastdata(
                            read61850FloatValue(
                                    String.format(isnull(map61850.get("CGAmp")), lastrecord.getDeviceaddr(),
                                            lastrecord.getPointaddr())));
                    alm += read61850IntValue(
                            String.format(isnull(map61850.get("CGAlm")), lastrecord.getDeviceaddr())) == 1 ? "铁芯全电流告警,"
                                    : "";
                } catch (SocketException e) {
                    if (Close()) {
                        txpdserviceimpl.UpdateStatus(ad, 1);
                        ComRunner.netmap.remove(ad.getId());
                    }
                } catch (Exception e) {
                    setText("读取数据出错！" + e.toString());
                }

                if (alm.equals("")) {
                    lastrecord.setLastalarmlevel(0);
                    lastrecord.setLastalarmmessage(alm);
                    GetNormalAlarm("油色谱" + lastrecord.getDeviceaddr(), lastrecord.getDevicegroup(),
                            lastrecord.getDeviceaddr(),
                            lastrecord.getPointaddr(),
                            lastrecord.getPointname(), "", false);
                    setText("无报警");
                } else {
                    lastrecord.setLastalarmlevel(2);
                    lastrecord.setLastalarmmessage(alm);
                    GetNormalAlarm("油色谱" + lastrecord.getDeviceaddr(), lastrecord.getDevicegroup(),
                            lastrecord.getDeviceaddr(),
                            lastrecord.getPointaddr(),
                            lastrecord.getPointname(), alm, true);
                    setText(alm);
                }
                SensorDatas(lastrecord, currrecord.getLastdata());
            }
            if (lastrecord.getPointaddr() == 10) {
                String alm = "";
                try {
                    currrecord.setLastdata(
                            read61850FloatValue(
                                    String.format(isnull(map61850.get("ClpGAmp")), lastrecord.getDeviceaddr(),
                                            lastrecord.getPointaddr())));
                    alm += read61850IntValue(
                            String.format(isnull(map61850.get("ClpGAlm")), lastrecord.getDeviceaddr())) == 1
                                    ? "夹件全电流告警,"
                                    : "";
                } catch (SocketException e) {
                    if (Close()) {
                        txpdserviceimpl.UpdateStatus(ad, 1);
                        ComRunner.netmap.remove(ad.getId());
                    }
                } catch (Exception e) {
                    setText("读取数据出错！" + e.toString());
                }
                if (alm.equals("")) {
                    lastrecord.setLastalarmlevel(0);
                    lastrecord.setLastalarmmessage(alm);
                    GetNormalAlarm("油色谱" + lastrecord.getDeviceaddr(), lastrecord.getDevicegroup(),
                            lastrecord.getDeviceaddr(),
                            lastrecord.getPointaddr(),
                            lastrecord.getPointname(), "", false);
                    setText("无报警");
                } else {
                    lastrecord.setLastalarmlevel(2);
                    lastrecord.setLastalarmmessage(alm);
                    GetNormalAlarm("油色谱" + lastrecord.getDeviceaddr(), lastrecord.getDevicegroup(),
                            lastrecord.getDeviceaddr(),
                            lastrecord.getPointaddr(),
                            lastrecord.getPointname(), alm, true);
                    setText(alm);
                }
                SensorDatas(lastrecord, currrecord.getLastdata());
            }

            if (lastrecord.getPointaddr() == 1) {
                String alm = "";
                try {
                    currrecord.setLastdata(
                            read61850FloatValue(
                                    String.format(isnull(map61850.get("IMTemp")), lastrecord.getDeviceaddr(),
                                            lastrecord.getPointaddr())));
                    alm += read61850IntValue(
                            String.format(isnull(map61850.get("IMTAlm")), lastrecord.getDeviceaddr())) == 1
                                    ? "油面油温计1报警,"
                                    : "";
                } catch (SocketException e) {
                    if (Close()) {
                        txpdserviceimpl.UpdateStatus(ad, 1);
                        ComRunner.netmap.remove(ad.getId());
                    }
                } catch (Exception e) {
                    setText("读取数据出错！" + e.toString());
                }
                if (alm.equals("")) {
                    lastrecord.setLastalarmlevel(0);
                    lastrecord.setLastalarmmessage(alm);
                    GetNormalAlarm("油色谱" + lastrecord.getDeviceaddr(), lastrecord.getDevicegroup(),
                            lastrecord.getDeviceaddr(),
                            lastrecord.getPointaddr(),
                            lastrecord.getPointname(), "", false);
                    setText("无报警");
                } else {
                    lastrecord.setLastalarmlevel(2);
                    lastrecord.setLastalarmmessage(alm);
                    GetNormalAlarm("油色谱" + lastrecord.getDeviceaddr(), lastrecord.getDevicegroup(),
                            lastrecord.getDeviceaddr(),
                            lastrecord.getPointaddr(),
                            lastrecord.getPointname(), alm, true);
                    setText(alm);
                }
                SensorDatas(lastrecord, currrecord.getLastdata());
            }

            if (lastrecord.getPointaddr() == 2) {
                String alm = "";
                try {
                    currrecord.setLastdata(
                            read61850FloatValue(
                                    String.format(isnull(map61850.get("IMTemp2")), lastrecord.getDeviceaddr(),
                                            lastrecord.getPointaddr())));
                    alm += read61850IntValue(
                            String.format(isnull(map61850.get("IMTAlm2")), lastrecord.getDeviceaddr())) == 1
                                    ? "油面油温计2报警,"
                                    : "";
                } catch (SocketException e) {
                    if (Close()) {
                        txpdserviceimpl.UpdateStatus(ad, 1);
                        ComRunner.netmap.remove(ad.getId());
                    }
                } catch (Exception e) {
                    setText("读取数据出错！" + e.toString());
                }
                if (alm.equals("")) {
                    lastrecord.setLastalarmlevel(0);
                    lastrecord.setLastalarmmessage(alm);
                    GetNormalAlarm("油色谱" + lastrecord.getDeviceaddr(), lastrecord.getDevicegroup(),
                            lastrecord.getDeviceaddr(),
                            lastrecord.getPointaddr(),
                            lastrecord.getPointname(), "", false);
                    setText("无报警");
                } else {
                    lastrecord.setLastalarmlevel(2);
                    lastrecord.setLastalarmmessage(alm);
                    GetNormalAlarm("油色谱" + lastrecord.getDeviceaddr(), lastrecord.getDevicegroup(),
                            lastrecord.getDeviceaddr(),
                            lastrecord.getPointaddr(),
                            lastrecord.getPointname(), alm, true);
                    setText(alm);
                }
                SensorDatas(lastrecord, currrecord.getLastdata());
            }

            if (lastrecord.getPointaddr() == 3) {
                String alm = "";
                try {
                    currrecord.setLastdata(
                            read61850FloatValue(
                                    String.format(isnull(map61850.get("HPTemp")), lastrecord.getDeviceaddr(),
                                            lastrecord.getPointaddr())));
                    alm += read61850IntValue(
                            String.format(isnull(map61850.get("HPTAlm")), lastrecord.getDeviceaddr())) == 1
                                    ? "绕组温度计报警,"
                                    : "";
                } catch (SocketException e) {
                    if (Close()) {
                        txpdserviceimpl.UpdateStatus(ad, 1);
                        ComRunner.netmap.remove(ad.getId());
                    }
                } catch (Exception e) {
                    setText("读取数据出错！" + e.toString());
                }
                if (alm.equals("")) {
                    lastrecord.setLastalarmlevel(0);
                    lastrecord.setLastalarmmessage(alm);
                    GetNormalAlarm("油色谱" + lastrecord.getDeviceaddr(), lastrecord.getDevicegroup(),
                            lastrecord.getDeviceaddr(),
                            lastrecord.getPointaddr(),
                            lastrecord.getPointname(), "", false);
                    setText("无报警");
                } else {
                    lastrecord.setLastalarmlevel(2);
                    lastrecord.setLastalarmmessage(alm);
                    GetNormalAlarm("油色谱" + lastrecord.getDeviceaddr(), lastrecord.getDevicegroup(),
                            lastrecord.getDeviceaddr(),
                            lastrecord.getPointaddr(),
                            lastrecord.getPointname(), alm, true);
                    setText(alm);
                }
                SensorDatas(lastrecord, currrecord.getLastdata());
            }
            if (lastrecord.getPointaddr() == 4) {
                String alm = "";
                try {
                    currrecord.setLastdata(
                            read61850FloatValue(
                                    String.format(isnull(map61850.get("OLLev")), lastrecord.getDeviceaddr(),
                                            lastrecord.getPointaddr())));
                    alm += read61850IntValue(
                            String.format(isnull(map61850.get("OLMin")), lastrecord.getDeviceaddr())) == 1
                                    ? "本体油位计浮球式油位低报,"
                                    : "";
                    alm += read61850IntValue(
                            String.format(isnull(map61850.get("OLMax")), lastrecord.getDeviceaddr())) == 1
                                    ? "本体油位计浮球式油位高报,"
                                    : "";
                } catch (SocketException e) {
                    if (Close()) {
                        txpdserviceimpl.UpdateStatus(ad, 1);
                        ComRunner.netmap.remove(ad.getId());
                    }
                } catch (Exception e) {
                    setText("读取数据出错！" + e.toString());
                }
                if (alm.equals("")) {
                    lastrecord.setLastalarmlevel(0);
                    lastrecord.setLastalarmmessage(alm);
                    GetNormalAlarm("油色谱" + lastrecord.getDeviceaddr(), lastrecord.getDevicegroup(),
                            lastrecord.getDeviceaddr(),
                            lastrecord.getPointaddr(),
                            lastrecord.getPointname(), "", false);
                    setText("无报警");
                } else {
                    lastrecord.setLastalarmlevel(2);
                    lastrecord.setLastalarmmessage(alm);
                    GetNormalAlarm("油色谱" + lastrecord.getDeviceaddr(), lastrecord.getDevicegroup(),
                            lastrecord.getDeviceaddr(),
                            lastrecord.getPointaddr(),
                            lastrecord.getPointname(), alm, true);
                    setText(alm);
                }
                SensorDatas(lastrecord, currrecord.getLastdata());
            }

        }
    }

    void SensorData(Txpdsensor txpd, float value) {
        if (txpd.getLastdenominator() == null) {
            setText("设备地址" + txpd.getDeviceaddr() + "的监测点" + txpd.getPointaddr() + " 未设置系数！");
            return;
        }
        float val =0;
        if(flag==0)
        {
             val =0;          
        }
        if(flag==1&&value!=0)
        {
            if(value<0)
                val = 0;
            else
             val = value + txpd.getLastdenominator();// 铁芯系数是加减法           
        }

        setText(txpd.getPointname() + "：" + val + " " + txpd.getLastunit());
        txpd.setLastdata(val);
        txpd.setLastdatatime(new Date());

        txpd.setLastalarmlevel(GetAlarmStatus(isnull(txpd.getLastdata()), isnull(txpd.getAlarmvalue()),
                isnull(txpd.getAlarmrelievevalue()), isnull(txpd.getWarnvalue()), isnull(txpd.getWarnrelievevalue()),
                isnull(txpd.getLastalarmlevel()), true, txpd.getLastname(), txpd.getDevicegroup(), txpd.getDeviceaddr(),
                txpd.getPointname(),
                txpd.getPointaddr()));

        // 报警消息
        txpd.setLastalarmmessage(GetAlarmMessage(txpd.getLastalarmlevel(), txpd.getLastname()));
        txpd.setLastcommunicationstatus(0);
        txpd.setLasthisdatatime(addHistory(txpdserviceimpl.getModel(txpd)));
        txpd.setAlarmvalue(null);
        txpd.setAlarmrelievevalue(null);
        txpd.setWarnvalue(null);
        txpd.setWarnrelievevalue(null);
        txpd.setPointname(null);
        txpd.setLastunit(null);
        txpd.setLastdenominator(null);
        if (txpdserviceimpl.Update(txpd, false) == 0) {
            setText("更新实时数据失败，请检查数据库连接");
        }
    }

    void SensorDatas(Txpdsensor txpd, float value) {
        if (txpd.getLastdenominator() == null) {
            setText("设备地址" + txpd.getDeviceaddr() + "的监测点" + txpd.getPointaddr() + " 未设置系数！");
            return;
        }
        float val = value + txpd.getLastdenominator();// 铁芯系数是加减法
        setText(txpd.getPointname() + "：" + val + " " + txpd.getLastunit());
        txpd.setLastdata(val);
        txpd.setLastdatatime(new Date());

        txpd.setLasthisdatatime(addHistory(txpdserviceimpl.getModel(txpd)));
        txpd.setAlarmvalue(null);
        txpd.setAlarmrelievevalue(null);
        txpd.setWarnvalue(null);
        txpd.setWarnrelievevalue(null);
        txpd.setPointname(null);
        txpd.setLastunit(null);
        txpd.setLastdenominator(null);
        if (txpdserviceimpl.Update(txpd, false) == 0) {
            setText("更新实时数据失败，请检查数据库连接");
        }
    }

    private Date addHistory(Txpdsensor sensor) {
        if (sensor != null) {
            if (sensor.getLasthisdatatime() == null) {
                add(sensor);
                return new Date();
            } else {
                long lasttime = 0;
                long nowtime = 0;
                try {
                    lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                    nowtime = HexUtil.todate(new Date()).getTime();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                int timersp = 60000;
                if (sensor.getLastalarmlevel() != 0) {
                    timersp = ad.getHisalarmtimersp() * 1000;
                } else {
                    timersp = ad.getHistimersp() * 1000;
                }
                if (lasttime + timersp < nowtime) {
                    add(sensor);
                    return new Date();
                }
            }
        }
        return null;
    }

    private void add(Txpdsensor sensor) {
        Txpdhistory his = new Txpdhistory();
        his.setStationid(sensor.getStationid());
        his.setDevicegroup(sensor.getDevicegroup());
        his.setDeviceaddr(sensor.getDeviceaddr());
        his.setAddrname(sensor.getAddrname());
        his.setPointaddr(sensor.getPointaddr());
        his.setPointname(sensor.getPointname());
        his.setData(sensor.getLastdata());
        his.setDatatime(sensor.getLastdatatime());
        his.setAlarmlevel(sensor.getLastalarmlevel());
        his.setAlarmmessage(sensor.getLastalarmmessage());
        his.setDenominator(sensor.getLastdenominator());
        his.setUnit(sensor.getLastunit());
        his.setName(sensor.getLastname());
        txpdserviceimpl.Add(his);
    }

    // 指定使用beanname为threadPool的线程池
    @Async("threadPool")
    public void startSendThread(Appdevice Appdevice) throws Exception {
        flag=0;
        int iflag=Appdevice.getAddrmin();

        for (int i = Appdevice.getAddrmin(); i <= Appdevice.getAddrmax(); i++)
        {
            Txpdsensor txpd = new Txpdsensor();
            txpd.setStationid(ad.getStationid());
            txpd.setDevicegroup(ad.getDevicegroup());
            txpd.setDeviceaddr(i);
            for (int j = 1; j <= 12; j++)
            {
                txpd.setPointaddr(j);
                
                Txpdsensor record = txpdserviceimpl.getModel(txpd);  
                if (record == null) {
                    setText("当前数据库无监测点：设备地址" + i + "的监测点" + j + " ！ 请先添加该监测点！");
                    continue;
                }
                if (record.getInuse() == 0) {
                    continue;
                }

                record.setLastdata(0f);
                if (txpdserviceimpl.Update(record, false) == 0) {
                    setText("更新实时数据失败，请检查数据库连接");
                }
            }            
        }

        checkType = "crc16";
        issend.put(Thread.currentThread().getId(), true);
        String cstr = "";
        String cmdtype = "";
        String nametype = "";
        int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
        while (issend.get(Thread.currentThread().getId()) != null) {
            if (isrun) {
                if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                    addrindex = Appdevice.getAddrmin();
                cstr = String.format(Appdevice.getCmd(), String.format("%02X", addrindex));
                cstr += CRC16.calcCrc16(cstr);
                if (Appdevice.getBrand().equals("STOM-I/E")) {
                    cstr += "16";
                }
                iflag++;
                if(iflag>=Appdevice.getAddrmax())
                {
                     flag =1;   
                     iflag=Appdevice.getAddrmin();                
                }

                Send(cstr);
                if(ad.getBrand().equals("3"))
                    read61850BSQ("");
                if (reSend[addrindex] > 10) {
                    txpdserviceimpl.UpdateStatus(ad, addrindex, 1);
                    reSend[addrindex] = 0;
                    addrindex++;
                }
                reSend[addrindex]++;

            } else if (rescode != 0) {
                setText(resmsg[rescode]);
            }
            Thread.sleep(timersp);
        }
    }

}
